/**
 * ReportGear(2011)
 */
package com.reportgear.report.model.cell.painter;

import java.awt.Color;
import java.awt.FontMetrics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.font.FontRenderContext;
import java.util.ArrayList;
import java.util.List;

import com.reportgear.report.core.api.compare.ComparatorUtils;
import com.reportgear.report.model.cell.style.FontStyle;
import com.reportgear.report.model.cell.style.Style;
import com.reportgear.report.model.cell.style.TextStyle;
import com.reportgear.report.model.cell.style.format.FormatterFactory;
import com.reportgear.report.view.grid.util.GraphHelper;
import com.sot.core.util.StringUtils;

/**
 * 单元格绘制实用类
 * 
 * @version 1.0 2011-4-17
 * @author <a herf="lexloo@gmail.com">lexloo</a>
 * @since Report 1.0
 */
public class CellPaintUtils {
	// 格式化器
	private static FormatterFactory formatterFactory = FormatterFactory.INSTANCE;

	/**
	 * 绘制格式化字符串
	 * 
	 * @param g2
	 *            图形对象
	 * @param rect
	 *            绘制区域
	 * @param content
	 *            内容
	 * @param style
	 *            样式
	 */
	public static void paintCellStyleString(Graphics2D g2, Rectangle rect, String str, Style style) {
		double w = rect.width;
		double h = rect.height;
		double ascent = 0;
		double x = 0;
		double y = 0;

		String content = str;

		if (StringUtils.isEmpty(content)) {
			return;
		}

		if (style == null) {
			style = Style.DEFAULT_STYLE;
		}

		if (!StringUtils.isEmpty(style.getFormatterKey())) {
			content = formatterFactory.getFormatterByKey(style.getFormatterKey()).format(content);
		}

		List<String> lines = getLineTextList(content, style, rect.width);

		FontRenderContext frContext = g2.getFontRenderContext();
		FontStyle font = style.getFontStyle();

		// Locale locale = ReportContext.getLocale();
		// if ((Locale.ENGLISH.equals(locale)) && (((str.startsWith("↓")) ||
		// (str.startsWith("→"))))) {
		// font = ReportFont.getInstance("Dialog", font.getStyle(),
		// font.getSize());
		// }
		if (!ComparatorUtils.equals(font, g2.getFont())) {
			g2.setFont(font);
		}
		Color color = font.getForeground();
		if (!ComparatorUtils.equals(color, g2.getPaint())) {
			g2.setPaint(color);
		}
		FontMetrics fm = g2.getFontMetrics();

		int count = lines.size();
		if (count == 0) {
			return;
		}

		Shape oldClip = g2.getClip();
		g2.clip(rect);
		g2.translate(rect.x, rect.y);

		double textH = fm.getHeight();
		double startY;
		switch (style.getVerticalAlignment()) {
		case MIDDLE:
			startY = (h + style.getSpacingBefore() - textH * count - style.getSpacingAfter()) / 2.0D;
			break;
		case TOP:
			startY = style.getSpacingBefore();
			break;
		case BOTTOM:
			startY = h - textH * count - style.getSpacingAfter();
			break;
		default:
			startY = (h - textH * count) / 2.0D;
		}

		for (int i = 0; i < count; i++) {
			String tmpStr = lines.get(i).trim();
			GraphHelper.drawString(g2, tmpStr, getDrawStringX(w, fm.stringWidth(tmpStr), style), startY + textH * i
					+ fm.getAscent());
		}
		g2.translate(-rect.x, -rect.y);
		g2.setClip(oldClip);
	}

	/**
	 * 字符串自动分行时，根据宽度对字符进行分割
	 * 
	 * @param text
	 *            显示的字符串
	 * @param style
	 *            样式
	 * @param width
	 *            宽度
	 * @return 分割后的字符串列表
	 */
	public static List getLineTextList(String text, Style style, double width) {
		List lineList = new ArrayList();
		if ((text == null) || (text.length() <= 0)) {
			return lineList;
		}
		if (style == null) {
			style = Style.DEFAULT_STYLE;
		}
		// //旋转字符串不处理
		// if (style.getRotation() != 0) {
		// lineList.add(text);
		// return lineList;
		// }
		FontStyle font = style.getFontStyle();
		FontMetrics fm = GraphHelper.getFontMetrics(font);

		// 如果不是自动换行，查找里面是否有换行符,根据换行符换行
		if (style.getTextStyle() != TextStyle.WORDWRAP) {
			StringBuffer buffer1 = new StringBuffer();
			for (int i = 0; i < text.length(); i++) {
				char c = text.charAt(i);
				if (c == '\\') {
					if ((i < text.length() - 1) && (text.charAt(i + 1) == 'n')) {
						++i;
						lineList.add(buffer1.toString());
						buffer1.delete(0, buffer1.length());
					} else {
						buffer1.append(c);
					}
				} else if (c == '\n') {
					lineList.add(buffer1.toString());
					buffer1.delete(0, buffer1.length());
				} else {
					buffer1.append(c);
				}
			}
			if (buffer1.length() > 0) {
				lineList.add(buffer1.toString());
				buffer1.delete(0, buffer1.length());
			}
			return lineList;
		}

		// 自动计算换行
		double textWidth = width - style.getPaddingLeft() - style.getPaddingRight();
		int j = 0;
		StringBuffer buffer2 = new StringBuffer();
		StringBuffer buffer3 = new StringBuffer();
		int tempWidth = 0;
		for (int i = 0; i < text.length(); i++) {
			if ((i > 0) && (Character.isLetter(text.charAt(i))) && (Character.isLetter(text.charAt(i - 1)))) {
				if (tempWidth + fm.charWidth(text.charAt(i)) > textWidth) {
					if (j > 0) {
						lineList.add(buffer2.toString());
						buffer2.delete(0, buffer2.length());
						j = 0;
					}
					lineList.add(buffer3.toString());
					buffer3.delete(0, buffer3.length());
					tempWidth = 0;
				}
				buffer3.append(text.charAt(i));
				tempWidth += fm.charWidth(text.charAt(i));
			} else if (text.charAt(i) == '\n') {
				if ((j + tempWidth > textWidth) && (buffer2.length() > 0)) {
					lineList.add(buffer2.toString());
					lineList.add(buffer3.toString());
				} else {
					buffer2.append(buffer3);
					lineList.add(buffer2.toString());
				}
				buffer2.delete(0, buffer2.length());
				j = 0;
				buffer3.delete(0, buffer3.length());
				tempWidth = 0;
			} else if ((text.charAt(i) == '\\') && (i < text.length() - 1) && (text.charAt(i + 1) == 'n')) {
				++i;
				if ((j + tempWidth > textWidth) && (buffer2.length() > 0)) {
					lineList.add(buffer2.toString());
					lineList.add(buffer3.toString());
				} else {
					buffer2.append(buffer3);
					lineList.add(buffer2.toString());
				}
				buffer2.delete(0, buffer2.length());
				j = 0;
				buffer3.delete(0, buffer3.length());
				tempWidth = 0;
			} else {
				if ((text.charAt(i) == '\\') && (i + 1 < text.length()) && (text.charAt(i + 1) == '\\')) {
					++i;
				}
				if ((j + tempWidth > textWidth) && (buffer2.length() > 0)) {
					lineList.add(buffer2.toString());
					buffer2.delete(0, buffer2.length());
					j = 0;
				}
				buffer2.append(buffer3);
				j += tempWidth;
				buffer3.delete(0, buffer3.length());
				tempWidth = 0;
				buffer3.append(text.charAt(i));
				tempWidth = fm.charWidth(text.charAt(i));
			}
		}
		if ((j + tempWidth > textWidth) && (buffer2.length() > 0)) {
			lineList.add(buffer2.toString());
			lineList.add(buffer3.toString());
		} else {
			buffer2.append(buffer3);
			lineList.add(buffer2.toString());
		}
		return lineList;
	}

	/**
	 * 获取字符串绘制的X位置
	 * 
	 * @param totalWidth
	 *            总宽度
	 * @param stringWidth
	 *            字符串宽度
	 * @param style
	 *            样式
	 * @return X位置
	 */
	private static double getDrawStringX(double totalWidth, double stringWidth, Style style) {
		switch (style.getHorizentalAlignment()) {
		case CENTER:
			return (totalWidth + style.getPaddingLeft() - stringWidth - style.getPaddingRight()) / 2.0D;
		case LEFT:
			return style.getPaddingLeft();
		case RIGHT:
			return totalWidth - stringWidth - style.getPaddingRight();
		default:
			return (totalWidth + style.getPaddingLeft() - stringWidth - style.getPaddingRight()) / 2.0D;
		}
	}
}
